/**
 * 
 */
package ro.dta.idbi.ui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import ro.dta.idbi.interfaces.ui.IMainFrame;
import ro.dta.idbi.model.AutoMedUtils;
import uk.ac.bbk.dcs.automed.wrappers.MySQLWrapperFactory;
import uk.ac.ic.doc.automed.IntegrityException;
import uk.ac.ic.doc.automed.modelmanagement.modeldef.SQLModelDef;
import uk.ac.ic.doc.automed.wrappers.AutoMedWrapper;
import uk.ac.ic.doc.automed.wrappers.AutoMedWrapperFactory;
import uk.ac.ic.doc.automed.wrappers.DataSourceException;
import uk.ac.ic.doc.automed.wrappers.PostgresWrapperFactory;

/**
 * Add new source to the repository frame
 * 
 * @author Tudor Dobrila
 */
public class AddSourceDialog extends JDialog implements ActionListener {

	private static final long serialVersionUID = 7380568023822656848L;

	private transient JComboBox<String> driversCombo;

	private final transient JTextField textFields[];

	private final transient IMainFrame parentFrame;

	/**
	 * AddSourceFrame class constructor
	 */
	public AddSourceDialog(final IMainFrame parentFrame) {
		super();
		this.parentFrame = parentFrame;

		setSize(500, 240);
		setTitle("Add New Source");
		setResizable(false);
		setModal(true);
		setLocationRelativeTo(null);

		final JGradientPanel mainPanel = new JGradientPanel(new GridBagLayout());
		final GridBagConstraints constr = new GridBagConstraints();

		// Add other labels
		final String[] labels = { "Driver: ", "Location: ", "Username: ", "Password: ",
				"Database Name:", "AutoMed Name:" };
		final String[] initialVals = { "", "jdbc:postgresql://localhost/", "postgres", "", "", "" };
		final int numPairs = labels.length;

		textFields = new JTextField[numPairs];

		constr.fill = GridBagConstraints.HORIZONTAL;
		constr.insets = new Insets(3, 3, 3, 3);

		for (int i = 0; i < numPairs; i++) {
			final JLabel l = new JLabel(labels[i], JLabel.TRAILING);
			constr.gridwidth = 1;
			constr.weightx = 0.2;
			constr.gridy = i;
			constr.gridx = 0;
			mainPanel.add(l, constr);

			constr.gridx = 1;
			constr.weightx = 0.8;
			constr.gridwidth = 3;
			if (i > 0) {
				textFields[i] = new JTextField(initialVals[i], 20);
				l.setLabelFor(textFields[i]);
				mainPanel.add(textFields[i], constr);
			} else {
				// final String[] drivers = { "org.postgresql.Driver", "com.mysql.jdbc.Driver" };
				final String[] drivers = { "org.postgresql.Driver" };
				driversCombo = new JComboBox<String>(drivers);
				l.setLabelFor(driversCombo);
				mainPanel.add(driversCombo, constr);
			}
		}

		final JButton connectBtn = new JButton("Test Credentials");
		constr.gridx = 1;
		constr.gridy = numPairs;
		constr.gridwidth = 1;
		constr.weightx = 0.0;
		connectBtn.addActionListener(this);
		connectBtn.setName("test");
		mainPanel.add(connectBtn, constr);

		final JButton confirmBtn = new JButton("Wrap Source");
		constr.fill = GridBagConstraints.NONE;
		constr.gridx = 3;
		constr.gridy = numPairs;
		constr.gridwidth = 1;
		constr.weightx = 0.0;
		confirmBtn.addActionListener(this);
		confirmBtn.setName("wrap");
		mainPanel.add(confirmBtn, constr);

		getContentPane().add(mainPanel);
	}

	@Override
	public void actionPerformed(final ActionEvent arg0) {
		final JButton source = (JButton) arg0.getSource();

		final String url = textFields[1].getText();
		final String driver = driversCombo.getSelectedItem().toString();
		final String username = textFields[2].getText();
		final String password = textFields[3].getText();
		final String dbName = textFields[4].getText();
		final String automedName = textFields[5].getText();

		if (source.getName().equals("test")) {
			try {
				AutoMedWrapper.selectNewAutoMedWrapper(username, password, null, driver, url);
				JOptionPane.showMessageDialog(this, "Connection was successful!", "Success",
						JOptionPane.INFORMATION_MESSAGE);
			} catch (IntegrityException e) {
				JOptionPane.showMessageDialog(this,
						"Could not connect to the data source!\r\nReason: " + e.getMessage(),
						"Error", JOptionPane.ERROR_MESSAGE);
			} catch (DataSourceException e) {
				JOptionPane.showMessageDialog(this,
						"Could not connect to the data source!\r\nReason: " + e.getMessage(),
						"Error", JOptionPane.ERROR_MESSAGE);
			}
		}

		if (source.getName().equals("wrap")) {
			// Wrap schema into the AutoMed repository
			AutoMedWrapperFactory wrapper = null;

			try {
				if (driversCombo.getSelectedIndex() == 0) {
					// PostgreSql
					wrapper = new PostgresWrapperFactory();
				} else {
					// MySQL
					wrapper = new MySQLWrapperFactory();
				}
				wrapper.getModelDefinition().setFeatures(SQLModelDef.PRIMARY_KEY);
				wrapper.getModelDefinition().setFeatures(SQLModelDef.FOREIGN_KEY);
				wrapper.getModelDefinition().setFeatures(SQLModelDef.DATA_TYPE);
				wrapper.getModelDefinition().setFeatures(SQLModelDef.NULL_CONSTRAINT);
			} catch (IntegrityException ex) {
				JOptionPane
						.showMessageDialog(
								this,
								"Could not set features for the wrapper factory! Source will NOT be added to the repository!\r\nReason: "
										+ ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
				return;
			}

			try {
				AutoMedUtils.wrapSchema(username, password, driver, url, wrapper, dbName,
						automedName);
				parentFrame.getRepositoryBrowser().refresh();
				parentFrame.getRepositoryBrowser().select(automedName);
				JOptionPane.showMessageDialog(this, "Schema has been wrapped successfully.",
						"Success", JOptionPane.INFORMATION_MESSAGE);
				parentFrame.setStatusBarText("Schema " + automedName
						+ " has been added to the repository.");
			} catch (Exception e) {
				JOptionPane.showMessageDialog(this,
						"Could not wrap data source! Source has NOT been added to the repository!\r\nReason: "
								+ e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
			}
		}

	}

}
